Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove djsonb dependency and move its relevant logic into Grout core #7

Merged
merged 7 commits into from
Jul 24, 2018

Conversation

jeancochrane
Copy link
Contributor

@jeancochrane jeancochrane commented Jul 23, 2018

Overview

Now that JSONB is supported in Django core, we no longer need most of the custom djsonb package. This PR removes the external dependency on djsonb and moves its lookup logic into Grout core. It also moves the djsonb test suite into this package in order to confirm that JSON filtering logic works.

Notes

  • I had to make a few small changes to the djsonb lookup logic in order to get it to work with Django's built-in JSONField type. Since those changes won't show up in this diff, I opened a separate PR over in djsonb in order to expose the diff.
  • The Lookup module is the only part of djsonb that we need to preserve, since it provides all of the logic that parses a query in the format that the Grout API expects (like jsonb={'a': {'b': {'c': {'_rule_type': 'containment', 'contains': [1, 2]}}}}) and turns it into SQL.
  • We had chatted in standup about whether it would be a better idea to update djsonb or bring the relevant portions into this package. Since all I need to preserve of djsonb is the lookup logic, I decided it would be best to bring it in here.
  • Normally, editing fields in old migrations is a no-go for backwards compatibility. However, I decided to do it in this PR for two reasons:
    1. If we can edit the old migrations to change djsonb.JsonBField types to the built-in JSONField type, we can purge the djsonb dependency entirely
    2. Since no apps are currently using Grout, migrations don't have to be reverse-compatible

Testing

Travis will run unit tests. To run them locally:

# Update containers.
./scripts/update

# Run tests.
./scripts/test

Closes azavea/grout-2018-fellowship#12.

Copy link
Contributor

@flibbertigibbet flibbertigibbet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the migrations could use a little cleanup. On running the test script:

CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0024_auto_20180716_1605, 0023_auto_20180717_1003 in grout).```

@jeancochrane
Copy link
Contributor Author

I don't see the migration labeled 0023_auto_20180717_1003 anywhere in the migrations folder in this branch. Any chance it's a holdover from another branch @flibbertigibbet?

@flibbertigibbet
Copy link
Contributor

Sure enough, I guess that one came from the remove-location-fields branch 👍

Copy link
Contributor

@flibbertigibbet flibbertigibbet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎊

Just a few notes. I've run the tests locally, but haven't tested it otherwise. Looking forward to seeing this all come together!

CHANGELOG.md Outdated
@@ -5,6 +5,8 @@
Changes we're making en route to version 2.0. When we cut a release, this
section will form the changelog for v2.0.

- Removed external `djsonb` dependency and moved its lookup logic into
Grout core ([#7](https://github.com/azavea/grout/pull/7)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎆

grout/lookups.py Outdated


class FilterTree:
"""This class should properly assemble the pieces necessary to write the WHERE clause of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: could this block comment be rephrased to open with a single line, separated from the rest with a blank line, per the docstring PEP?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do. I'll flesh out all the docstrings in this module.

grout/lookups.py Outdated

for rule in self.rules:
# If not a properly registered rule type
if not self.is_rule(rule[1]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we know index 1 will be in bounds for rule? Could it be made more obvious what data is at the 0 and 1 offsets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question! Based on the parameter list for the methods that use these values (like FilterTree.containment_filter), it looks like rule[0] corresponds to the path of the nested query, while rule[1] corresponds to the rule itself. Both elements have to exist, since self.get_rules can only return either A) an empty list or B) a list of two-tuples.

I'll add this info in a comment and redo the iteration assignment to change it from:

for rule in self.rules:

To something more expressive;

for path, rule in self.rules:

grout/lookups.py Outdated
@classmethod
def containment_filter(cls, path, rule):
"""Filter for objects that contain the specified value at some location"""
template = reconstruct_object(path[1:])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the questions about rule above, could it be made more obvious what the slices of path contain, and why it's safe to assume path has a length of at least two?

@jeancochrane jeancochrane merged commit c217cda into develop Jul 24, 2018
@jeancochrane jeancochrane deleted the remove-djsonb branch July 24, 2018 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants